home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
ACORNUSERS
/
EMULATOR
/
MAGICKIT
/
assembler
/
c
/
command
< prev
next >
Wrap
Text File
|
1998-04-14
|
6KB
|
391 lines
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "defs.h"
#include "externs.h"
char filename[128];
/* pseudo operations processor */
pseudo(int *ip)
{
switch(opval) {
case 0: /* .db */
do_db(ip);
break;
case 1: /* .dw */
do_dw(ip);
break;
case 2: /* .equ / = */
do_assign(ip);
break;
case 3: /* .page */
do_page(ip);
break;
case 4: /* .org */
do_org(ip);
break;
case 5: /* .bank */
do_bank(ip);
break;
case 6: /* .incbin */
do_incbin(ip);
break;
case 7: /* .include */
do_include(ip);
break;
case 8: /* .incchr/spr/pal */
case 9:
case 10:
do_pcx(ip);
break;
case 11: /* .macro */
do_macro(ip);
break;
case 12: /* .endm */
do_endm(ip);
break;
case 13: /* .list */
check_eol(ip);
clist = 1;
xlist = 1;
break;
case 14: /* .mlist */
check_eol(ip);
mlist = 1;
break;
case 15: /* .nolist */
check_eol(ip);
clist = 0;
break;
case 16: /* .nomlist */
check_eol(ip);
mlist = 0;
break;
case 17: /* .rsset */
do_rsset(ip);
break;
case 18: /* .rs */
do_rs(ip);
break;
}
}
/* .db pseudo */
do_db(int *ip)
{
char c;
int count;
int i;
int tvalue;
labldef(loccnt, 1);
loadlc(loccnt, 0);
while (isspace(prlnbuf[++(*ip)])); /* field */
count = 0;
do {
if (prlnbuf[*ip] == '"') {
while ((tvalue = prlnbuf[++(*ip)]) != '"') {
if (tvalue == 0) {
error("Unterminated ASCII string!");
return;
}
if (tvalue == '\\')
switch(tvalue = prlnbuf[++(*ip)]) {
case 'r':
tvalue = '\r';
break;
case 'n':
tvalue = '\n';
break;
case 't':
tvalue = '\t';
break;
}
loccnt++;
if (pass == LAST_PASS) {
loadv(loccnt-1, tvalue, count);
if (++count >= 3) {
println();
clearln();
count = 0;
loadlc(loccnt, 0);
}
}
}
++(*ip);
}
else {
if (!evaluate(ip, 0)) {
loccnt++;
return;
}
loccnt++;
if (value > 0xFF) {
error("Operand field size error!");
return;
}
else if (pass == LAST_PASS) {
loadv(loccnt-1, value, count);
if (++count >= 3) {
println();
clearln();
count = 0;
loadlc(loccnt, 0);
}
}
}
} while ((c = prlnbuf[(*ip)++]) == ',');
if (c != ';' && c != '\0')
error("Syntax error!");
if ((pass == LAST_PASS) && (count != 0))
println();
}
/* .dw pseudo */
do_dw(int *ip)
{
char c;
int i;
labldef(loccnt, 1);
loadlc(loccnt, 0);
do {
if (!evaluate(ip, 0)) {
loccnt += 2;
return;
}
loccnt += 2;
if (pass == LAST_PASS) {
loadv(loccnt-2, value, 0, 1);
loadv(loccnt-1, value>>8, 1, 1);
println();
clearln();
loadlc(loccnt, 0);
}
} while ((c = prlnbuf[(*ip)++]) == ',');
if (c != ';' && c != '\0')
error("Syntax error!");
}
/* = pseudo */
do_assign(int *ip)
{
if (!evaluate(ip, ';'))
return;
labldef(value, 0);
if (pass == LAST_PASS) {
loadlc(value, 1);
println();
}
}
/* .page pseudo */
do_page(int *ip)
{
labldef(loccnt, 1);
if (!evaluate(ip, ';'))
return;
if (value < 0) {
error("Page index out of range!");
return;
} else if (value < 8) {
page = value;
} else {
if (value & 0x7FFF1FF8) {
error("Invalid page address!");
return;
}
page = value >> 13;
}
if (pass == LAST_PASS) {
loadlc(page << 13, 1);
println();
}
}
/* .org pseudo */
do_org(int *ip)
{
if (!evaluate(ip, ';'))
return;
if (undef != 0) {
error("Undefined symbol in operand field!");
return;
}
if (value & 0xFFFF0000) {
error("Address out of range!");
return;
}
page = (value >> 13) & 0x07;
value &= 0x1FFF;
loccnt = value;
labldef(value, 1);
if (pass == LAST_PASS) {
loadlc(loccnt | (page << 13), 1);
println();
}
}
/* .bank pseudo */
do_bank(int *ip)
{
labldef(loccnt, 1);
if (!evaluate(ip, ';'))
return;
if ((value < 0) || (value > 127)) {
error("Bank index out of range!");
return;
}
bank_offset[bank] = loccnt;
bank_page[bank] = page;
bank = value;
page = bank_page[bank];
loccnt = bank_offset[bank];
glablptr = NULL;
if (pass == LAST_PASS) {
loadlc(bank, 1);
println();
}
}
/* .incbin pseudo */
do_incbin(int *ip)
{
FILE *f;
int size;
int i;
labldef(loccnt, 1);
if (!get_filename(ip))
return;
if ((f = fopen(filename, "rb")) == NULL) {
error("Can not open file!");
return;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
if (((bank << 13) + loccnt + size) > (8192 * 128)) {
fclose(f);
error("File too big!");
return;
}
if (pass == LAST_PASS) {
fread(&rom[bank][loccnt], 1, size, f);
loadlc(loccnt, 0);
println();
}
fclose(f);
bank += (loccnt + size) >> 13;
loccnt = (loccnt + size) & 0x1FFF;
if (bank > max_bank) {
if (loccnt)
max_bank = bank;
else
max_bank = bank - 1;
}
}
/* .include pseudo */
do_include(int *ip)
{
labldef(loccnt, 1);
if (!get_filename(ip))
return;
if (pass == LAST_PASS)
println();
if (open_input(filename) == -1) {
error("Can not open file!");
return;
}
}
/* .rsset pseudo */
do_rsset(int *ip)
{
labldef(loccnt, 1);
if (!evaluate(ip, ';'))
return;
if (value & 0xFFFF0000) {
error("Address out of range!");
return;
}
rsbase = value;
if (pass == LAST_PASS) {
loadlc(rsbase, 1);
println();
}
}
/* .rs pseudo */
do_rs(int *ip)
{
labldef(rsbase, 0);
if (!evaluate(ip, ';'))
return;
if (value & 0xFFFFFF00) {
error("Size out of range!");
return;
}
if (pass == LAST_PASS) {
loadlc(rsbase, 1);
println();
}
rsbase += value;
}
/* get a file name from prlnbuf */
get_filename(int *ip)
{
char c;
int i;
char conv[128];
char *p, *q;
while (isspace(prlnbuf[++(*ip)]));
if (prlnbuf[(*ip)++] != '\"') {
error("Invalid file name!");
return (0);
}
i = 0;
while (((c = prlnbuf[(*ip)++]) != '\"') && (i < 128))
filename[i++] = c;
if ((i == 128) || (i == 0)) {
error("Invalid file name!");
return (0);
}
filename[i] = '\0';
if (!(p = strrchr(filename, '.'))) return(1);
*(p++) = '\0';
q = strrchr(filename, '.');
if (!q) q = strrchr(filename, ':');
if (q) {
q++;
strncpy(conv, filename, q - filename);
strcat(conv, p);
strcat(conv, q);
} else {
strcpy(conv, p);
strcat(conv, ".");
strcat(conv, filename);
}
strcpy(filename, conv);
return (1);
}